/***************************************************************************
 *  Filename: slavecommunicator.h
 *  Class: slavecommunicator
 *
 *  Copyright 2012  Xander van Kooten
 *  <xandervk@gmail.com>
 *
 *  Copyright 2012  Mario Henrique Voorsluys
 *  <forcaeluz@gmail.com>
 *
 ****************************************************************************/

/*
 *
 * This file is part of Parsax-Remote-Controller.
 *
 *    Parsax-Remote-Controller is free software: you can redistribute it
 *    and/or modify it under the terms of the GNU General Public License
 *    as published by the Free Software Foundation, either version 3 of the
 *    License, or (at your option) any later version.
 *
 *    Parsax-Remote-Controller is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Parsax-Remote-Controller.
 *    If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef SLAVECOMMUNICATOR_H
#define SLAVECOMMUNICATOR_H

//Qt includes
#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QNetworkInterface>

//Project includes
#include "CCC-Communication_global.h"
#include "messageparser.h"

/*!
 \brief This class handles the network communication in the Slave.

 The SlaveCommunicator is responsible for listening to incoming connections
 at the slave computer. Once there is an incomming connection, it's accepted
 establishing a connection between Master and Slave.

 The data is read and checked for validity. Further parsing of the message is
 done in MessageParser.

 The SlaveCommunicator also handles the outgoing data from the slave to the master.
 It's function is to send the data if there is an open connection.

*/
class CCCCOMMUNICATIONSHARED_EXPORT SlaveCommunicator : public QObject
{
    Q_OBJECT
public:

    /*!
     \brief Object constructor

     \param parent Sets the parent of QObject

     The constructor initializes some variables, but does not setup the listening, because
     that should be done in other places than only the constructor.
    */
    explicit SlaveCommunicator(QObject *parent=0);
    /*!
     \brief Object destructor

    */
    ~SlaveCommunicator();

    /*!
     \brief Starts listening at a specific address to a specific port.

     \param listenAddres The adress where the object should listen. Default is to all adresses.
     \param port Port from the incoming connections. Default in this project is 33300.

     Initializing the SlaveCommunicator means start listening to incomming connections. When there are
     different networkcards a specific listening adress could be given from the card where the
     incomming connections come from. If the object can listen to incoming connections from all the
     addresses, use 0.0.0.0. The incoming connections should connect throught the specific port.
    */
    void initialize(QString listenAddres, int port);

    /*!
     \brief Send data throught the network

     \param data Data to be send.

     The possibility of sending data is checked by first checking the existance of a connection between
     master and slave, and checking if the connection is open for write actions. If this is the case, the
     data is send.
    */
    void sendData(QByteArray data);
signals:

    /*!
     \brief Emitted when valid data is received.

     \param data The received data

     Data is considered valid after header and tail check. The header should be: "\#", while the tail
     should be "\#\#".
    */
    void validDataReceived(QString data);

    void connectionEstablished();

private:
    QTcpServer tcpListener; /*!< Listens to a port, and handle incoming connections */
    QTcpSocket *openMasterConnection; /*!< An open connection with the master. Only one is allowed.*/
private slots:
    /*!
     \brief Setup the #openMasterConnection when #tcpListener has a new connection.

    */
    void setupConnection();
    /*!
     \brief Read data received in the #openMasterConnection

    */
    void readData();
    /*!
     \brief Handles the process of a broken communication pipe

     When the connection is closed, the connection object is deleted, being replaced by a new one
     when an incomming connection is accepted.
    */
    void connectionClosed();
};

#endif // SLAVECOMMUNICATOR_H
